<template>
  <div class="art-full-height">
    <div class="tree-container">
      <div class="left-sidebar mb-2">
        <ElCard class="art-table-card" shadow="never">
          <el-radio-group v-model="tabPosition">
            <el-radio-button v-for="(name, id) in blockNames" :key="id" :label="id">
              {{ name || '分组' + id }}
            </el-radio-button>
          </el-radio-group>
        </ElCard>
      </div>
      <div class="mr-2">
        <Search v-model="searchForm" @search="handleSearch"></Search>
      </div>
      <div class="right-content art-full-height">
        <ElCard class="art-table-card" shadow="never">
          <div class="mb-4">
            <el-button v-auth="'common:config:add'" type="primary" @click="showDialog('add')"
              >新增</el-button
            >
          </div>
          <el-form>
            <el-form-item
              v-for="item in groupByBlock[tabPosition] ?? []"
              :key="item?.id"
              class="config-form-item"
            >
              <div class="config-item-row">
                <div class="config-item-label">{{ item?.name }}</div>
                <div class="config-item-control">
                  <el-input v-if="item?.type == 1" v-model="item.value" />
                  <el-switch
                    v-else-if="item?.type == 2"
                    v-model="item.value"
                    active-value="1"
                    inactive-value="0"
                    @change="(val) => handleSwitchChange(item, val)"
                  />
                  <ImageSelector
                    v-else-if="item?.type == 3"
                    v-model="item.value"
                    :multiple="false"
                  />
                </div>
                <div class="config-item-key">{{ item?.key }}</div>
                <div class="config-item-action">
                  <el-button
                    type="danger"
                    v-auth="'common:config:del'"
                    size="small"
                    @click="() => handleDelete(item)"
                  >
                    删除
                  </el-button>
                </div>
              </div>
            </el-form-item>
            <el-form-item>
              <el-button v-auth="'common:config:save'" type="primary" @click="handleSave"
                >保存</el-button
              >
            </el-form-item>
          </el-form>
        </ElCard>
      </div>
    </div>
    <Dialog
      v-model:visible="dialogVisible"
      :type="dialogType"
      :user-data="currentUserData"
      @submit="handleDialogSubmit"
    />
  </div>
</template>

<script setup lang="ts">
  import ImageSelector from '@/components/image-selector/index.vue'
  import { ref, onMounted, computed } from 'vue'
  import Search from './modules/search.vue'
  import Dialog from './modules/dialog.vue'
  import {
    fetchConfigList,
    editConfigApi,
    fetchConfigCateTypes,
    deleteConfigApi
  } from '@/api/common'
  import { ElMessageBox } from 'element-plus'
  interface ConfigItem {
    id: number
    name: string
    block: string | number
    type: number
    value: any
    key: string
  }
  // 搜索表单
  const searchForm = ref({
    search: undefined,
    status: '',
    created_at: undefined
  })
  const dialogType = ref('add')
  const dialogVisible = ref(false)
  const currentUserData = ref<Partial<any>>({})
  const configList = ref<ConfigItem[]>([])
  // 保存原始数据用于对比
  let originalList: ConfigItem[] = []
  const loading = ref(false)
  const tabPosition = ref('') // block分组值，初始化为空，之后设置为第一个分组

  const blockNames = ref<Record<string, string>>({})

  // 分组（使用字符串 key）
  const groupByBlock = computed<Record<string, ConfigItem[]>>(() => {
    const groups: Record<string, ConfigItem[]> = {}
    configList.value.forEach((item) => {
      const key = String(item.block)
      if (!groups[key]) groups[key] = []
      groups[key].push(item)
    })
    return groups
  })

  onMounted(async () => {
    await getBlockNames()
    await getConfig()
  })
  watch(tabPosition, async (val, oldVal) => {
    if (val && val !== oldVal) {
      await getConfig(searchForm.value)
    }
  })
  const getBlockNames = async () => {
    try {
      const res: any = await fetchConfigCateTypes({ status: 1 })
      // 兼容：数组、{ data: [...] } 或 分页 { data: { data: [...] } }
      const list = Array.isArray(res)
        ? res
        : Array.isArray(res?.data)
          ? res.data
          : Array.isArray(res?.data?.data)
            ? res.data.data
            : []
      blockNames.value = {}
      list.forEach((item: any) => {
        blockNames.value[String(item.id)] = item.name
      })
      // 如果没有指定 tabPosition，初始化为第一个分类 id
      const keys = Object.keys(blockNames.value)
      if (!tabPosition.value && keys.length) {
        tabPosition.value = keys[0]
      }
    } catch (e) {
      console.error('getBlockNames error', e)
    }
  }

  const getConfig = async (params: Record<string, any> = {}): Promise<void> => {
    loading.value = true
    try {
      const payload = Object.assign({}, params, { block: Number(tabPosition.value) })
      const res: any = await fetchConfigList(payload)
      const list = Array.isArray(res)
        ? res
        : Array.isArray(res?.data)
          ? res.data
          : Array.isArray(res?.data?.data)
            ? res.data.data
            : []
      configList.value = list as ConfigItem[]
      originalList = JSON.parse(JSON.stringify(list))
      const blocks = Object.keys(groupByBlock.value)
      if (blocks.length && !blocks.includes(tabPosition.value)) {
        tabPosition.value = blocks[0]
      }
    } catch (error) {
      console.error('getConfig error', error)
      throw error instanceof Error ? error : new Error('获取配置失败')
    } finally {
      loading.value = false
    }
  }

  async function handleSave() {
    // 只保存被修改过的项
    const saveList = (groupByBlock.value[tabPosition.value] || [])
      .filter((item) => {
        const original = originalList.find((o) => o.id === item.id)
        return original && item.value !== original.value
      })
      .map((item) => ({
        id: item.id,
        value: item.value
      }))
    try {
      await editConfigApi(saveList)
      ElMessage.success('已成功保存')
    } catch {
      // ElMessage.error('保存失败')
    }
  }

  async function handleSwitchChange(item: ConfigItem, val: any) {
    // 只保存当前开关项
    try {
      await editConfigApi({ id: item.id, value: val })
      ElMessage.success('已成功保存')
    } catch {
      // 可选：提示失败
      // ElMessage.error('保存失败')
    }
  }
  /**
   * 搜索处理
   * @param params 参数
   */
  const handleSearch = (params: Record<string, any>) => {
    Object.assign(searchForm.value, params)
    getConfig(searchForm.value)
  }
  const showDialog = (type: 'add'): void => {
    const tabPositionValue = tabPosition.value
    dialogType.value = type
    currentUserData.value = { block: tabPositionValue }
    nextTick(() => {
      dialogVisible.value = true
    })
  }
  /**
   * 处理弹窗提交事件
   */
  const handleDialogSubmit = async () => {
    try {
      dialogVisible.value = false
      currentUserData.value = {}
      await getConfig(searchForm.value)
    } catch (error) {
      console.error('提交失败:', error)
    }
  }
  const handleDelete = (row?: any) => {
    // 单个删除
    if (row) {
      ElMessageBox.confirm(`确定要删除【${row.name}】吗？`, '删除', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'error'
      }).then(async () => {
        await deleteConfigApi([row.id])
        ElMessage.success('删除成功')
        await getConfig(searchForm.value)
      })
      return
    }
  }
</script>

<style scoped>
  .tree-container {
    box-sizing: border-box;
    gap: 16px;

    .left-sidebar {
      flex-shrink: 0;
      min-width: 0;
      height: 70px;
    }

    .right-content {
      flex-grow: 1;
      min-width: 0;
      height: 100%;
    }

    .art-table-card {
      display: flex;
      flex-direction: column;
      height: 100%;
    }
  }

  /* Replace $device-ipad with a valid value, e.g., 1024px */
  @media screen and (max-width: 1024px) {
    .tree-container {
      display: block;
      gap: 0;
      height: auto;

      .left-sidebar {
        width: 100%;
        height: auto;
        margin-bottom: 10px;
      }
    }
  }
  .config-form-item {
    margin-bottom: 18px;
    .config-item-row {
      display: flex;
      align-items: center;
      width: 100%;
    }
    .config-item-label {
      width: 120px;
      min-width: 80px;
      color: #333;
      font-size: 14px;
      text-align: left;
      flex-shrink: 0;
      padding-right: 12px;
    }
    .config-item-control {
      flex: 1;
      min-width: 0;
      display: flex;
      align-items: center;
      .el-input,
      .el-switch,
      .ImageSelector {
        width: 100%;
      }
    }
    .config-item-key {
      width: 120px;
      min-width: 80px;
      color: #999;
      font-size: 12px;
      text-align: right;
      flex-shrink: 0;
      padding-left: 12px;
      margin-right: 6px;
      white-space: nowrap;
    }
  }
</style>
